package com.ec.fb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ec.api.client.UserClient;
import com.ec.api.domain.dto.UserDTO;
import com.ec.common.constant.CacheConstants;
import com.ec.common.domain.PageVO;
import com.ec.common.exception.BadRequestException;
import com.ec.common.utils.BeanUtils;
import com.ec.common.utils.CacheClient;
import com.ec.fb.domain.dto.*;
import com.ec.fb.domain.po.Feedback;
import com.ec.fb.enums.FeedbackStatus;
import com.ec.fb.mapper.FeedbackMapper;
import com.ec.fb.service.FeedbackService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class FeedbackServiceImpl implements FeedbackService {
    private final FeedbackMapper feedbackMapper;
    private final UserClient userClient;
    private final CacheClient cacheClient;

    @Override
    public FeedbackResponseDTO submitFeedback(FeedbackCreateRequestDTO requestDTO, Long userId) {
        Feedback feedback = new Feedback();
        BeanUtils.copyProperties(requestDTO, feedback);
        feedback.setUserId(userId);
        feedback.setStatus(FeedbackStatus.PENDING);
        feedbackMapper.insert(feedback);
        return convertToResponseDTO(feedback);
    }

    @Override
    public FeedbackResponseDTO replyFeedback(FeedbackReplyRequestDTO requestDTO, Integer adminId) {
        Feedback feedback = feedbackMapper.selectById(requestDTO.getFeedbackId());
        if (feedback == null) {
            throw new BadRequestException("反馈不存在");
        }
        feedback.setReply(requestDTO.getReply());
        feedback.setRepliedByAdminId(adminId);
        feedback.setStatus(FeedbackStatus.REPLIED);
        feedbackMapper.updateById(feedback);
        return convertToResponseDTO(feedback);
    }

    @Override
    public PageVO<FeedbackResponseDTO> listFeedbacks(Integer pageNum, Integer pageSize, Integer rating) {
        Page<Feedback> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Feedback> queryWrapper = new LambdaQueryWrapper<>();
        if (rating != null) {
            queryWrapper.eq(Feedback::getRating, rating);
        }
        queryWrapper.orderByDesc(Feedback::getCreatedAt);
        page = feedbackMapper.selectPage(page, queryWrapper);
        return PageVO.of(page, this::convertToResponseDTO);
    }

    @Override
    public PageVO<FeedbackResponseDTO> listAdminFeedbacks(Integer pageNum, Integer pageSize, String status, String userQuery) {
        Page<Feedback> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Feedback> queryWrapper = new LambdaQueryWrapper<>();

        // 按状态筛选
        if (status != null && !status.isEmpty()) {
            queryWrapper.eq(Feedback::getStatus, FeedbackStatus.of(status));
        }

        // 按用户ID或用户名筛选
        if (userQuery != null && !userQuery.isEmpty()) {
            try {
                // 尝试解析为用户ID
                Long userId = Long.parseLong(userQuery);
                UserDTO user = userClient.getUserById(userId).getData();
                if (user != null) {
                    queryWrapper.eq(Feedback::getUserId, userId);
                } else {
                    // 用户ID不存在，返回空页
                    return PageVO.empty((long) pageNum, (long) pageSize);
                }
            } catch (NumberFormatException e) {
                // 不是数字，作为用户名模糊搜索
                List<UserDTO> users = (List<UserDTO>) userClient.searchUsersByName(userQuery);
                if (users.isEmpty()) {
                    return PageVO.empty((long) pageNum, (long) pageSize);
                }
                List<Long> userIds = users.stream().map(UserDTO::getId).collect(Collectors.toList());
                queryWrapper.in(Feedback::getUserId, userIds);
            }
        }

        queryWrapper.orderByDesc(Feedback::getCreatedAt);
        page = feedbackMapper.selectPage(page, queryWrapper);
        return PageVO.of(page, this::convertToResponseDTO);
    }

    @Override
    public PageVO<FeedbackResponseDTO> listMyFeedbacks(Integer pageNum, Integer pageSize, Long userId) {
        try {
            String cacheKey = CacheConstants.CACHE_FEEDBACK_KEY + userId + ":" + pageNum + ":" + pageSize;
            Page<Feedback> result = cacheClient.queryWithPassThrough(
                    cacheKey,
                    userId,
                    Page.class,
                    id -> {
                        Page<Feedback> page = new Page<>(pageNum, pageSize);
                        LambdaQueryWrapper<Feedback> queryWrapper = new LambdaQueryWrapper<>();
                        queryWrapper.eq(Feedback::getUserId, id);
                        queryWrapper.orderByDesc(Feedback::getCreatedAt);
                        return feedbackMapper.selectPage(page, queryWrapper);
                    },
                    15L,
                    TimeUnit.MINUTES
            );
            return result != null ? PageVO.of(result, this::convertToResponseDTO) : PageVO.empty((long) pageNum, (long) pageSize);
        } catch (Exception e) {
            Page<Feedback> page = new Page<>(pageNum, pageSize);
            LambdaQueryWrapper<Feedback> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Feedback::getUserId, userId);
            queryWrapper.orderByDesc(Feedback::getCreatedAt);
            page = feedbackMapper.selectPage(page, queryWrapper);
            return PageVO.of(page, this::convertToResponseDTO);
        }
    }

    @Override
    public FeedbackStatsDTO getFeedbackStats() {
        Long positiveCount = feedbackMapper.selectCount(
                new LambdaQueryWrapper<Feedback>().ge(Feedback::getRating, 4));
        Long negativeCount = feedbackMapper.selectCount(
                new LambdaQueryWrapper<Feedback>().le(Feedback::getRating, 3));
        Long totalCount = feedbackMapper.selectCount(null);

        FeedbackStatsDTO stats = new FeedbackStatsDTO();
        stats.setPositiveCount(positiveCount);
        stats.setNegativeCount(negativeCount);
        if (totalCount > 0) {
            stats.setPositivePercentage((double) positiveCount / totalCount * 100);
            stats.setNegativePercentage((double) negativeCount / totalCount * 100);
        } else {
            stats.setPositivePercentage(0.0);
            stats.setNegativePercentage(0.0);
        }
        return stats;
    }

    private FeedbackResponseDTO convertToResponseDTO(Feedback feedback) {
        FeedbackResponseDTO dto = new FeedbackResponseDTO();
        BeanUtils.copyProperties(feedback, dto);
        dto.setStatus(feedback.getStatus().getValue());
        // 获取用户名
        UserDTO user = userClient.getUserById(feedback.getUserId()).getData();
        dto.setUserName(user != null ? user.getFullName() : "未知用户");
        return dto;
    }
}